package com.kinyx.framework.image;

import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;

import com.kinyx.framework.annotation.assist.CanNotNull;
import com.kinyx.framework.annotation.assist.ReturnNotNull;
import com.kinyx.framework.annotation.assist.Tester;

import lombok.AccessLevel;
import lombok.NoArgsConstructor;

/**
 * 图片修剪工具类
 */
@Tester("com.kinyx.framework.image.KImageCropper_Tester_")
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class KImageCropper {

	/**
	 * 渲染图片对象
	 * @param image 图片对象
	 * @param scale 缩放比例
	 * @return 新图像
	 */
	@ReturnNotNull
	private static BufferedImage render(@CanNotNull final BufferedImage image, @CanNotNull final double scale) {
		final AffineTransformOp ato = new AffineTransformOp(AffineTransform.getScaleInstance(scale, scale), null);
		return ato.filter(image, null);
	}

	/**
	 * 等比例缩放图片（根据最小宽度与最小高度计算图片的缩放比后进行缩放）
	 * @param image 图片对象
	 * @param minWidth 最小宽度
	 * @param minHeight 最小高度
	 * @return 新图像
	 */
	@ReturnNotNull
	public static BufferedImage zoom(@CanNotNull final BufferedImage image, @CanNotNull final int minWidth, @CanNotNull final int minHeight) {
		final ImageSize size = new ImageSize(image.getWidth(), image.getHeight(), minWidth, minHeight);
		return render(image, size.zoomRatio);
	}

	/**
	 * 等比例缩放图片后去除超出部分
	 * @param image 图片对象
	 * @param width 宽度
	 * @param height 高度
	 * @return 新图像
	 */
	@ReturnNotNull
	public static BufferedImage zoomDiscard(@CanNotNull final BufferedImage image, @CanNotNull final int width, @CanNotNull final int height) {
		final ImageSize size = new ImageSize(image.getWidth(), image.getHeight(), width, height);
		final BufferedImage renderedImage = render(image, size.zoomRatio);
		final int w = size.diffWidth == 0 ? size.resultWidth : size.resultWidth - size.diffWidth;
		final int h = size.diffHeight == 0 ? size.resultHeight : size.resultHeight - size.diffHeight;
		return render(renderedImage, 1).getSubimage(0, 0, w, h);
	}

	/**
	 * 剪切图片
	 * @param image 图片对象
	 * @param x X坐标起始点
	 * @param y Y坐标起始点
	 * @param width 宽度
	 * @param height 高度
	 * @return 新图像
	 */
	@ReturnNotNull
	public static BufferedImage cut(@CanNotNull final BufferedImage image, @CanNotNull final int x, @CanNotNull final int y, @CanNotNull final int width, @CanNotNull final int height) {
		return render(image, 1).getSubimage(x, y, width, height);
	}

	/**
	 * 先等比例缩放图片（根据最小宽度与最小高度计算图片的缩放比后进行缩放）再剪切
	 * @param image 图片对象
	 * @param zoomMinWidth 缩放最小宽度
	 * @param zoomMinHeight 缩放最小高度
	 * @param cutX 剪切X坐标起始点
	 * @param cutY 剪切Y坐标起始点
	 * @param cutWidth 剪切宽度
	 * @param cutHeight 剪切高度
	 * @return 新图像
	 */
	@ReturnNotNull
	public static BufferedImage crop(@CanNotNull final BufferedImage image, @CanNotNull final int zoomMinWidth, @CanNotNull final int zoomMinHeight, @CanNotNull final int cutX, @CanNotNull final int cutY, @CanNotNull final int cutWidth, @CanNotNull final int cutHeight) {
		final ImageSize size = new ImageSize(image.getWidth(), image.getHeight(), zoomMinWidth, zoomMinHeight);
		final BufferedImage renderedImage = render(image, size.zoomRatio);
		return render(renderedImage, 1).getSubimage(cutX, cutY, cutWidth, cutHeight);
	}

}
